﻿using System;
using GeoAPI.Geometries;
using YJKGridTopologyCal.Geometries;
using YJKGridTopologyCal.Mathematics;

namespace YJKGridTopologyCal.Triangulate.QuadEdge
{
	public static class TrianglePredicate
	{
		public static bool IsInCircleNonRobust(Coordinate a, Coordinate b, Coordinate c, Coordinate p)
		{
			return (a.X * a.X + a.Y * a.Y) * TrianglePredicate.TriArea(b, c, p) - (b.X * b.X + b.Y * b.Y) * TrianglePredicate.TriArea(a, c, p) + (c.X * c.X + c.Y * c.Y) * TrianglePredicate.TriArea(a, b, p) - (p.X * p.X + p.Y * p.Y) * TrianglePredicate.TriArea(a, b, c) > 0.0;
		}

		public static bool IsInCircleNormalized(Coordinate a, Coordinate b, Coordinate c, Coordinate p)
		{
			double num = a.X - p.X;
			double num2 = a.Y - p.Y;
			double num3 = b.X - p.X;
			double num4 = b.Y - p.Y;
			double num5 = c.X - p.X;
			double num6 = c.Y - p.Y;
			double num7 = num * num4 - num3 * num2;
			double num8 = num3 * num6 - num5 * num4;
			double num9 = num5 * num2 - num * num6;
			double num10 = num * num + num2 * num2;
			double num11 = num3 * num3 + num4 * num4;
			double num12 = num5 * num5 + num6 * num6;
			return num10 * num8 + num11 * num9 + num12 * num7 > 0.0;
		}

		private static double TriArea(Coordinate a, Coordinate b, Coordinate c)
		{
			return (b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X);
		}

		public static bool IsInCircleRobust(Coordinate a, Coordinate b, Coordinate c, Coordinate p)
		{
			return TrianglePredicate.IsInCircleNormalized(a, b, c, p);
		}

		public static bool IsInCircleDDSlow(Coordinate a, Coordinate b, Coordinate c, Coordinate p)
		{
			DD dd = DD.ValueOf(p.X);
			DD dd2 = DD.ValueOf(p.Y);
			DD dd3 = DD.ValueOf(a.X);
			DD dd4 = DD.ValueOf(a.Y);
			DD dd5 = DD.ValueOf(b.X);
			DD dd6 = DD.ValueOf(b.Y);
			DD dd7 = DD.ValueOf(c.X);
			DD dd8 = DD.ValueOf(c.Y);
			DD dd9 = dd3.Multiply(dd3).Add(dd4.Multiply(dd4)).Multiply(TrianglePredicate.TriAreaDDSlow(dd5, dd6, dd7, dd8, dd, dd2));
			DD y = dd5.Multiply(dd5).Add(dd6.Multiply(dd6)).Multiply(TrianglePredicate.TriAreaDDSlow(dd3, dd4, dd7, dd8, dd, dd2));
			DD y2 = dd7.Multiply(dd7).Add(dd8.Multiply(dd8)).Multiply(TrianglePredicate.TriAreaDDSlow(dd3, dd4, dd5, dd6, dd, dd2));
			DD y3 = dd.Multiply(dd).Add(dd2.Multiply(dd2)).Multiply(TrianglePredicate.TriAreaDDSlow(dd3, dd4, dd5, dd6, dd7, dd8));
			return dd9.Subtract(y).Add(y2).Subtract(y3).ToDoubleValue() > 0.0;
		}

		private static DD TriAreaDDSlow(DD ax, DD ay, DD bx, DD by, DD cx, DD cy)
		{
			return bx.Subtract(ax).Multiply(cy.Subtract(ay)).Subtract(by.Subtract(ay).Multiply(cx.Subtract(ax)));
		}

		public static bool IsInCircleDDFast(Coordinate a, Coordinate b, Coordinate c, Coordinate p)
		{
			DD lhs = (DD.Sqr(a.X) + DD.Sqr(a.Y)) * TrianglePredicate.TriAreaDDFast(b, c, p);
			DD rhs = (DD.Sqr(b.X) + DD.Sqr(b.Y)) * TrianglePredicate.TriAreaDDFast(a, c, p);
			DD rhs2 = (DD.Sqr(c.X) + DD.Sqr(c.Y)) * TrianglePredicate.TriAreaDDFast(a, b, p);
			DD rhs3 = (DD.Sqr(p.X) + DD.Sqr(p.Y)) * TrianglePredicate.TriAreaDDFast(a, b, c);
			return (lhs - rhs + rhs2 - rhs3).ToDoubleValue() > 0.0;
		}

		private static DD TriAreaDDFast(Coordinate a, Coordinate b, Coordinate c)
		{
			DD lhs = (DD.ValueOf(b.X) - a.X) * (DD.ValueOf(c.Y) - a.Y);
			DD rhs = (DD.ValueOf(b.Y) - a.Y) * (DD.ValueOf(c.X) - a.X);
			return lhs - rhs;
		}

		public static bool IsInCircleDDNormalized(Coordinate a, Coordinate b, Coordinate c, Coordinate p)
		{
			DD dd = DD.ValueOf(a.X) - p.X;
			DD dd2 = DD.ValueOf(a.Y) - p.Y;
			DD dd3 = DD.ValueOf(b.X) - p.X;
			DD dd4 = DD.ValueOf(b.Y) - p.Y;
			DD dd5 = DD.ValueOf(c.X) - p.X;
			DD dd6 = DD.ValueOf(c.Y) - p.Y;
			DD rhs = dd * dd4 - dd3 * dd2;
			DD rhs2 = dd3 * dd6 - dd5 * dd4;
			DD rhs3 = dd5 * dd2 - dd * dd6;
			DD lhs = dd * dd + dd2 * dd2;
			DD lhs2 = dd3 * dd3 + dd4 * dd4;
			DD lhs3 = dd5 * dd5 + dd6 * dd6;
			return (lhs * rhs2 + lhs2 * rhs3 + lhs3 * rhs).ToDoubleValue() > 0.0;
		}

		public static bool IsInCircleCC(Coordinate a, Coordinate b, Coordinate c, Coordinate p)
		{
			Coordinate c2 = Triangle.Circumcentre(a, b, c);
			double num = a.Distance(c2);
			return p.Distance(c2) - num <= 0.0;
		}

		private static void CheckRobustInCircle(Coordinate a, Coordinate b, Coordinate c, Coordinate p)
		{
			bool flag = TrianglePredicate.IsInCircleNonRobust(a, b, c, p);
			bool flag2 = TrianglePredicate.IsInCircleDDSlow(a, b, c, p);
			bool flag3 = TrianglePredicate.IsInCircleCC(a, b, c, p);
			Triangle.Circumcentre(a, b, c);
			if (flag == flag2)
			{
			}
		}
	}
}
